﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NetVoxLab.Framework.Model;

namespace NetVoxLab.Framework.Task1
{
    public class Task1Runner
    {
        public IEnumerable<Uri> GetUniqueUrls(INode node)
        {
            if (node == null)
                throw new ArgumentNullException("node");

            var urls = new List<Uri>();
            var type = node as TypeB;
            if (type != null)
            {
                urls.AddRange(GetSubUrls(type));

                // check for duplicate
                if (!urls.Any(url => url.OriginalString == type.Url.OriginalString))
                    urls.Add(type.Url);
            }
            else if (node is IMultiNode)
            {
                urls.AddRange(GetSubUrls(node));
            }

            return urls;
        }

        public IEnumerable<INode> GetNodesByName(string name, INode root)
        {
            if (string.IsNullOrEmpty(name))
                return new List<INode>();

            if (root == null)
                throw new ArgumentNullException("root");

            var nodes = new List<INode>();
            var propValue = (string) Utilities.GetPropValue("name", root);
            if (string.IsNullOrEmpty(propValue))
                return new List<INode>();

            if (string.Compare(propValue, name, StringComparison.OrdinalIgnoreCase) == 0)
                nodes.Add(root);

            var multiNode = root as IMultiNode;
            if (multiNode != null)
            {
                foreach (INode subNode in multiNode.Nodes)
                {
                    IEnumerable<INode> subNodes = GetNodesByName(name, subNode);
                    nodes.AddRange(subNodes);
                }
            }

            return nodes;
        }

        private IEnumerable<Uri> GetSubUrls(INode node)
        {
            var multiNode = node as IMultiNode;
            if (multiNode == null)
                return new List<Uri>();

            var urls = new List<Uri>();

            foreach (INode subNode in multiNode.Nodes)
            {
                IEnumerable<Uri> subUrls = GetUniqueUrls(subNode);

                foreach (Uri subUrl in subUrls)
                {
                    bool isContains = urls.Any(x => x.OriginalString == subUrl.OriginalString);
                    if (!isContains)
                        urls.Add(subUrl);
                }
            }

            return urls;
        }
    }
}
